package requests

import (
	"gohub/app/http/requests/validators"
	"gohub/pkg/auth"
	"mime/multipart"

	"github.com/gin-gonic/gin"
	"github.com/thedevsaddam/govalidator"
)

type UserUpdateProfileRequest struct {
	Name         string `valid:"name" json:"name"`
	City         string `valid:"city" json:"city"`
	Introduction string `valid:"introduction" json:"introduction"`
}

type UserUpdateEmailRequest struct {
	Email      string `valid:"email" json:"email,omitempty"`
	VerifyCode string `valid:"verify_code" json:"verify_code,omitempty"`
}

type UserUpdatePhoneRequest struct {
	Phone      string `valid:"phone" json:"phone,omitempty"`
	VerifyCode string `valid:"verify_code" json:"verify_code,omitempty"`
}

type UserUpdatePasswordRequest struct {
	Password           string `valid:"password" json:"password,omitempty"`
	NewPassword        string `valid:"new_password" json:"new_password,omitempty"`
	NewPasswordConfirm string `valid:"new_password_confirm" json:"new_password_confirm,omitempty"`
}

type UserUpdateAvatarRequest struct {
	Avatar *multipart.FileHeader `valid:"avatar" form:"avatar"`
}

func UserUpdateProfile(data interface{}, c *gin.Context) map[string][]string {
	uid := auth.CurrentUID(c)
	return validate(data,
		// 校验规则
		govalidator.MapData{
			"name":         []string{"required", "alpha_num", "between:3,20", "not_exists:users,name," + uid},
			"city":         []string{"min_cn:2", "max_cn:20"},
			"introduction": []string{"min_cn:4", "max_cn:240"},
		},
		// 校验错误提示信息
		govalidator.MapData{
			"name": []string{
				"required:用户名为必填项",
				"alpha_num:用户名格式错误，只允许数字和英文",
				"between:用户名长度需在 3~20 之间",
				"not_exists:用户名已被占用",
			},
			"city": []string{
				"min_cn:城市需至少 2 个字",
				"max_cn:城市不能超过 20 个字",
			},
			"introduction": []string{
				"min_cn:描述长度需至少 4 个字",
				"max_cn:描述长度不能超过 240 个字",
			},
		},
	)
}

func UserUpdateEmail(data interface{}, c *gin.Context) map[string][]string {
	curUser := auth.CurrentUser(c)

	errs := validate(data,
		// 校验规则
		govalidator.MapData{
			"email": []string{
				"required",
				"min:4", "max:30",
				"email",
				"not_exists:users,email",
				"not_in:" + curUser.Email,
			},
			"verify_code": []string{"required", "digits:6"},
		},
		// 校验错误提示信息
		govalidator.MapData{
			"email": []string{
				"required:Email 为必填项",
				"min:Email 长度需大于 4",
				"max:Email 长度需小于 30",
				"email:Email 格式不正确，请提供有效的邮箱地址",
				"not_exists:Email 已被占用",
				"not_in:新的 Email 与旧 Email 一致",
			},
			"verify_code": []string{
				"required:验证码答案必填",
				"digits:验证码长度必须为 6 位的数字",
			},
		},
	)

	_data := data.(*UserUpdateEmailRequest)
	errs = validators.ValidateVerifyCode(_data.Email, _data.VerifyCode, errs)

	return errs
}

func UserUpdatePhone(data interface{}, c *gin.Context) map[string][]string {
	curUser := auth.CurrentUser(c)

	errs := validate(data,
		// 校验规则
		govalidator.MapData{
			"phone": []string{
				"required",
				"digits:11",
				"not_exists:users,phone",
				"not_in:" + curUser.Phone,
			},
			"verify_code": []string{"required", "digits:6"},
		},
		// 校验错误提示信息
		govalidator.MapData{
			"phone": []string{
				"required:手机号为必填项，参数名称 phone",
				"digits:手机号长度必须为 11 位的数字",
				"not_exists:手机号已被占用",
				"not_in:新的手机与旧手机号一致",
			},
			"verify_code": []string{
				"required:验证码答案必填",
				"digits:验证码长度必须为 6 位的数字",
			},
		},
	)

	_data := data.(*UserUpdatePhoneRequest)
	errs = validators.ValidateVerifyCode(_data.Phone, _data.VerifyCode, errs)

	return errs
}

func UserUpdatePassword(data interface{}, c *gin.Context) map[string][]string {
	errs := validate(data,
		// 校验规则
		govalidator.MapData{
			"password":             []string{"required", "min:6"},
			"new_password":         []string{"required", "min:6"},
			"new_password_confirm": []string{"required", "min:6"},
		},
		// 校验错误提示信息
		govalidator.MapData{
			"password": []string{
				"required:旧密码为必填项",
				"min:密码长度需大于 6",
			},
			"new_password": []string{
				"required:新密码为必填项",
				"min:密码长度需大于 6",
			},
			"new_password_confirm": []string{
				"required:确认密码框为必填项",
				"min:密码长度需大于 6",
			},
		},
	)

	// 确保 comfirm 密码正确
	_data := data.(*UserUpdatePasswordRequest)
	errs = validators.ValidatePasswordConfirm(_data.NewPassword, _data.NewPasswordConfirm, errs)

	return errs
}

func UserUpdateAvatar(data interface{}, c *gin.Context) map[string][]string {
	return validateFile(c, data,
		// 校验规则
		govalidator.MapData{
			// size 的单位为 bytes
			// - 1024 bytes 为 1kb
			// - 1048576 bytes 为 1mb
			// - 20971520 bytes 为 20mb
			"file:avatar": []string{"required", "ext:png,jpg,jpeg", "size:20971520"},
		},
		// 校验错误提示信息
		govalidator.MapData{
			"file:avatar": []string{
				"required:必须上传图片",
				"ext:ext头像只能上传 png, jpg, jpeg 任意一种的图片",
				"size:头像文件最大不能超过 20MB",
			},
		},
	)
}
